﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using Portfolio.Entities;
using Portfolio.Repository.Common;
using Portfolio.Repository.Interfaces;

namespace Portfolio.Repository.Categories
{
    /// <summary>
    /// Klasa Repozytorium Kategorii
    /// </summary>
    public class CategoriesRepository : GenericRepository
    {
        /// <summary>
        /// Konstruktor dziedziczy z klasy Generycznej (ogólnej) Repozytorium
        /// </summary>
        /// <param name="context"></param>
        public CategoriesRepository(ObjectContext context) : base(context) { }

        
        /// <summary>
        /// Metoda użytkownika
        /// Pobiera z bazy danych Kategorie z jednej rodziny
        /// W widoku ustawione jest active=true oraz depthlevel=0
        /// </summary>
        /// <param name="articleCategoryID">Rodzic kategorii</param>
        /// <returns>Lista kategorii (widok)</returns>
        public List<CategoriesDropDownListV> GetCategoriesByActiveFlag(int articleCategoryID)
        {
            if (articleCategoryID == 0)
            {
                return GetAll<CategoriesDropDownListV>().OrderBy(b => b.SeqAllCategory).ToList();
            }
            else
            {
                return Find<CategoriesDropDownListV>(a => a.ArticleCategoryID != articleCategoryID).OrderBy(b => b.SeqAllCategory).ToList();
            }
        }

        /// <summary>
        /// Metoda użytkownika
        /// Pobiera z bazy danych wyszukane Kategorie
        /// </summary>
        /// <param name="title">Tytuł</param>
        /// <param name="categoryIDID">Rodzic</param>
        /// <param name="status">Status</param>
        /// <param name="active">Aktywny</param>
        /// <returns>Lista Kategorii</returns>
        public List<ArtcileCategoriesGridV> GetCategoryBySearch(string title, int? categoryIDID, int? status, bool? active)
        {
            if (categoryIDID == null && status == null && active == null)
            {
                return Find<ArtcileCategoriesGridV>(a => a.Name.Contains(title)).OrderBy(b => b.SeqAllCategory).ToList();
            }
            else
                if (categoryIDID == null && status == null && active != null)
                {
                    return Find<ArtcileCategoriesGridV>(a => a.Name.Contains(title) && a.ActiveFlag == active).OrderBy(b => b.SeqAllCategory).ToList();
                }
                else
                    if (categoryIDID == null && status != null && active == null)
                    {
                        return Find<ArtcileCategoriesGridV>(a => a.Name.Contains(title) && a.Status == status).OrderBy(b => b.SeqAllCategory).ToList();
                    }
                    else
                        if (categoryIDID != null && status == null && active == null)
                        {
                            return Find<ArtcileCategoriesGridV>(a => a.Name.Contains(title) && a.ArticleCategoryIDID == categoryIDID).OrderBy(b => b.SeqAllCategory).ToList();
                        }
                        else
                            if (categoryIDID == null && status != null && active != null)
                            {
                                return Find<ArtcileCategoriesGridV>(a => a.Name.Contains(title) && a.ActiveFlag == active && a.Status == status).OrderBy(b => b.SeqAllCategory).OrderBy(b => b.SeqAllCategory).ToList();
                            }
                            else
                                if (categoryIDID != null && status == null && active != null)
                                {
                                    return Find<ArtcileCategoriesGridV>(a => a.Name.Contains(title) && a.ArticleCategoryIDID == categoryIDID && a.ActiveFlag == active).OrderBy(b => b.SeqAllCategory).ToList();
                                }
                                else
                                    if (categoryIDID != null && status != null && active == null)
                                    {
                                        return Find<ArtcileCategoriesGridV>(a => a.Name.Contains(title) && a.ArticleCategoryID == categoryIDID && a.Status == status).OrderBy(b => b.SeqAllCategory).ToList();
                                    }
                                    else
                                    {
                                        return Find<ArtcileCategoriesGridV>(a => a.Name.Contains(title) && a.ArticleCategoryID == categoryIDID && a.ActiveFlag == active && a.Status == status).OrderBy(b => b.SeqAllCategory).ToList();
                                    }
        }

        /// <summary>
        /// Metoda użytkownika
        /// Pobiera z bazy danych konkretną kategorie
        /// </summary>
        /// <param name="articleCategoryID">id konkretnej kategorii</param>
        /// <returns>Kategoria</returns>
        public ArticleCategoryT GetCategoryByIdCategory(int articleCategoryID)
        {            
            return Single<ArticleCategoryT>(a => a.ArticleCategoryID == articleCategoryID); 
        }

        /// <summary>
        /// Metoda użytkownika
        /// Pobiera z bazy danych kategorie o konkretnej całościowej kolejności
        /// </summary>
        /// <param name="seqAll">Kolejność</param>
        /// <returns>Kategoria</returns>
        public ArticleCategoryT GetCategoryBySeqAll(int seqAll)
        {
            return Single<ArticleCategoryT>(a => a.SeqAllCategory == seqAll);
        }

        /// <summary>
        /// Metoda użytkownika
        /// Pobiera z bazy danych kategorie o kolejnosci częsciowej i rodzicu 
        /// </summary>
        /// <param name="seq">Kolejność danej rodziny</param>
        /// <param name="articleCategoryIDID">Id rodzica</param>
        /// <returns>Kategoria</returns>
        public ArticleCategoryT GetCategoryBySeqAndIDIDCategoryID(int seq, int? articleCategoryIDID)
        {
            if (articleCategoryIDID == null)
            {
                return Single<ArticleCategoryT>(a => a.SeqCategory == seq && a.ArticleCategoryIDID == null);
            }
            else
            {
                return Single<ArticleCategoryT>(a => a.SeqCategory == seq && a.ArticleCategoryIDID == articleCategoryIDID);
            }
        }

        /// <summary>
        /// Metoda użytkownika
        /// Pobiera z bazy danych listę kategorii z danego rodzica
        /// </summary>
        /// <param name="articleCategoryIDID">Id rodzica lub null</param>
        /// <returns>Lista kategorii</returns>
        public List<ArticleCategoryT> GetCategoryByIDIDCategoryIsNull(int? articleCategoryIDID)
        {
            if (articleCategoryIDID == null)
            {
                return Find<ArticleCategoryT>(a => a.ArticleCategoryIDID == null).ToList();
            }
            else
            {
                return Find<ArticleCategoryT>(a => a.ArticleCategoryIDID == articleCategoryIDID).ToList();
            }
        }

        /// <summary>
        /// Metoda użytkwonika
        /// Pobiera wsyztskie kategorie
        /// </summary>
        /// <returns>Lista kategorii</returns>
        public List<ArticleCategoryT> GetAll()
        {
            return GetAll<ArticleCategoryT>().ToList();
        }

        /// <summary>
        /// Metoda użytkownika
        /// Pobiera wszystkie pokategorie z danego rodzica
        /// </summary>
        /// <param name="articleCategoryIDID">Id rodzica kategorii</param>
        /// <returns>Kategoria</returns>
        public ArticleCategoryT GetCategoryByIdIdCategory(int? articleCategoryIDID)
        {
            return Single<ArticleCategoryT>(a => a.ArticleCategoryID == articleCategoryIDID);
        }

        /// <summary>
        /// Metoda użytkownika
        /// Modyfikuje kategorię
        /// </summary>
        /// <param name="category">Kategoria do mydyfikacji</param>
        public void UpdateCategory(ArticleCategoryT category)
        {
            Update<ArticleCategoryT>(category); 
        }

        /// <summary>
        /// Metoda użytkownika
        /// Usuwa kategoria
        /// </summary>
        /// <param name="category">Kategoria do usnięcia</param>
        public void DeleteCategory(ArticleCategoryT category)
        {
            Delete(category);
        }

        /// <summary>
        /// Metoda użytkownika
        /// Wprowadza nową kategorię
        /// </summary>
        /// <param name="category">Nowa kategoria</param>
        /// <returns>czy się udało</returns>
        public int InsertCategory(ArticleCategoryT category)
        {
            return Add(category);
        }        
    }
}
